#!/bin/sh
#
# $FreeBSD$
#

# PROVIDE: ix-warden
# BEFORE: jail

. /etc/rc.freenas

WARDENCONF="/usr/local/etc/warden.conf"
WARDEN_UPDATE=/data/warden-update

_w()
{
 	local args="$*"

	if [ -n "${args}" ]
	then
		logger -t "ix-warden" "${args}"
		${args}
		return $?
	fi

	return 0
}


get_jc_path()
{
	local IFS="|"

	${FREENAS_SQLITE_CMD} ${RO_FREENAS_CONFIG} "
	SELECT
		jc_path
	FROM
		jails_jailsconfiguration
	ORDER BY
		-id
	LIMIT 1
	" | while read jc_path
	do
		echo "${jc_path}"
	done
}

get_jc_dataset()
{
	local jc_path
	
	jc_path="${1}"
	if [ -z "${jc_path}" ]
	then
		return 1
	fi

	zfs list -H|awk -v jc_path="${jc_path}" '$5 == jc_path { print $1 }'
	return 0
}

get_arch()
{
	if [ "$(uname -m)" = "amd64" ]
	then
		echo "x64"
	else
		echo "x86"
	fi
}

get_release()
{
	uname -r|cut -f1 -d-
}

get_ta()
{
	local sysctl_path
	local path
	local arch

	path="${1}"
	if [ ! -d "${path}" ] 
	then
		return 1
	fi

	sysctl_path="${path}/sbin/sysctl"
	if [ ! -f "${sysctl_path}" ]
	then
		return 1
	fi

	arch="$(file -b "${sysctl_path}" | awk '{ print $2 }')"
	if [ "${arch}" = "64-bit" ] ; then
		arch="x64"
	else
		arch="x86"
	fi

	echo "${arch}"
	return 0
}

migrate_warden_templates()
{
	local templates
	local jc_path
	local jc_dataset
	local arch
	local version

	jc_path="$(get_jc_path)"
	jc_dataset="$(get_jc_dataset "${jc_path}")"

	if [ -z "${jc_path}" -o -z "${jc_dataset}" ]
	then
		return
	fi

	arch="$(get_arch)"
	version="$(get_release)"
	templates="pluginjail portjail standard"

	for t in ${templates}
	do
		local template
		local ta
		local tv
		local pool
		local altroot

		template="${jc_path}/.warden-template-${t}"
		if [ ! -d "${template}" ]
		then
			continue
		fi	

		ta="$(get_ta "${template}")"
		if [ "$?" != "0" ]
		then
			continue
		fi		

		tv="$(get_tv "${template}")"
		if [ "$?" != "0" ]
		then
			continue
		fi

		template="${jc_dataset}/.warden-template-${t}"
		if [ "${tv}" = "${version}" -a \
			"${ta}" = "${arch}" ]
		then
			continue
		fi

		newt="${jc_dataset}/.warden-template-${t}-${tv}-${ta}"
		newmp="${jc_path}/.warden-template-${t}-${tv}-${ta}"
		oldmpg="${jc_path}/.warden-template-${t}"

		if [ -d "${newmp}" ]
		then
			local timestr="$(date +'%Y%m%d%H%M%S')"

			newt="${jc_dataset}/.warden-template-${t}-${tv}-${ta}-${timestr}"
			newmp="${jc_path}/.warden-template-${t}-${tv}-${ta}-${timestr}"
		fi

		pool="$(echo "${jc_dataset}"|cut -f1 -d '/')"
		if [ -n "${pool}" ]
		then
			altroot="$(zpool get -H altroot "${pool}"|awk '{ print $3 }')"
		fi

		_w zfs set mountpoint='none' "${template}"
		if [ "$?" != "0" ]
		then
			continue
		fi

		_w zfs rename -f "${template}" "${newt}"
		if [ "$?" != "0" ]
		then
			continue
		fi

		_w mv "${oldmpg}" "${newmp}"
		if [ "$?" != "0" ]
		then
			continue
		fi

		if [ -n "${altroot}" ]
		then
			newmp="${newmp##${altroot}}"
		fi

		_w zfs set mountpoint="${newmp}" "${newt}"
		if [ "$?" != "0" ]
		then
			continue
		fi
	done
}

get_tv()
{
	local sysctl_path
	local version
	local path

	path="${1}"
	if [ ! -d "${path}" ] 
	then
		return 1
	fi

	sysctl_path="${path}/sbin/sysctl"
	if [ ! -f "${sysctl_path}" ]
	then
		return 1
	fi

	version="$(file -b "${sysctl_path}"|cut -d ',' -f 6|awk '{ print $3 }')"
	if [ -n "${version}" ]
	then
		echo "${version}"
	fi
	return 0
}

generate_warden_conf()
{
	local tmpfile
	local wconf="${WARDENCONF}"
	local jc_path=$(${FREENAS_SQLITE_CMD} ${RO_FREENAS_CONFIG} "
		SELECT
			jc_path
		FROM
			jails_jailsconfiguration

		ORDER BY
			-id
		LIMIT 1
	")

	if [ -n "${jc_path}" -a -d "${jc_path}" ]
	then
		if [ ! -f "${wconf}" ]
		then
			cat<<-__EOF__>>"${wconf}"
			NIC: re0
			WTMP: /usr/jails
			JDIR: /usr/jails
__EOF__
		fi

		tmpfile=$(mktemp /tmp/.warden.XXXXXX)
		sed -e "s#^\(JDIR:.*\)#JDIR: ${jc_path}#g" \
			-e "s#^\(WTMP:.*\)#WTMP: ${jc_path}#g" "${wconf}" > "${tmpfile}"
		if [ "$?" = "0" -a -s "${tmpfile}" ]
		then
			mv "${tmpfile}" "${wconf}"
		fi
	fi
}

ix_warden_start()
{
	RO_FREENAS_CONFIG=$(ro_sqlite ${name} 2> /tmp/${name}.fail && rm /tmp/${name}.fail)
	trap 'rm -f ${RO_FREENAS_CONFIG}' EXIT
	generate_warden_conf
	migrate_warden_templates
}

name="ix-warden"
start_cmd='ix_warden_start'
            
load_rc_config $name
run_rc_command "$1"
